﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Miris.HumanMilkAnalyser.DataModel;
using Miris.HumanMilkAnalyser.Service.Shared;
using Miris.HumanMilkAnalyser.Service.Validation;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel
{
    public class FurtherSuggestionViewModel : MyViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the FurtherSuggestionViewModel class.
        /// </summary>
        public FurtherSuggestionViewModel(IDataService dataService)
            : base(dataService) { }

        public override void ResetProperties()
        {
            base.ResetProperties();

            InitializeAnalysisItemList();
            InitializeBreastfeedingSignificance();

            SelectedAnalysisItem = AnalysisItemList[0];
        }

        /// <summary>
        /// The <see cref="SelectedAnalysisItem" /> property's name.
        /// </summary>
        public const string SelectedAnalysisItemPropertyName = "SelectedAnalysisItem";

        private AnalysisItem _selectedAnalysisItem = null;

        /// <summary>
        /// Sets and gets the SelectedAnalysisItem property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public AnalysisItem SelectedAnalysisItem
        {
            get
            {
                return _selectedAnalysisItem;
            }

            set
            {
                if (_selectedAnalysisItem == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedAnalysisItemPropertyName);
                _selectedAnalysisItem = value;
                RaisePropertyChanged(SelectedAnalysisItemPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="AnalysisItemList" /> property's name.
        /// </summary>
        public const string AnalysisItemListPropertyName = "AnalysisItemList";

        private ObservableCollection<AnalysisItem> _analysisItemList = new ObservableCollection<AnalysisItem>();

        /// <summary>
        /// Sets and gets the AnalysisItemList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<AnalysisItem> AnalysisItemList
        {
            get
            {
                return _analysisItemList;
            }

            set
            {
                if (_analysisItemList == value)
                {
                    return;
                }

                RaisePropertyChanging(AnalysisItemListPropertyName);
                _analysisItemList = value;
                RaisePropertyChanged(AnalysisItemListPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="CurrentBreastfeedingSignificance" /> property's name.
        /// </summary>
        public const string CurrentBreastfeedingSignificancePropertyName = "CurrentBreastfeedingSignificance";

        private BreastfeedingSignificance _currentBreastfeedingSignificance = null;

        /// <summary>
        /// Sets and gets the CurrentBreastfeedingSignificance property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public BreastfeedingSignificance CurrentBreastfeedingSignificance
        {
            get
            {
                return _currentBreastfeedingSignificance;
            }

            set
            {
                if (_currentBreastfeedingSignificance == value)
                {
                    return;
                }

                RaisePropertyChanging(CurrentBreastfeedingSignificancePropertyName);
                _currentBreastfeedingSignificance = value;
                RaisePropertyChanged(CurrentBreastfeedingSignificancePropertyName);
            }
        }

        private RelayCommand _saveCommand;

        /// <summary>
        /// Gets the SaveCommand.
        /// </summary>
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand ?? (_saveCommand = new RelayCommand(
                    ExecuteSaveCommand,
                    CanExecuteSaveCommand));
            }
        }

        private void ExecuteSaveCommand()
        {
            try
            {
                // Update AnalysisItemList.
                ServiceFactory.CreateAnalysisItemService().Update(AnalysisItemList);

                // Update BreastfeedingSignificance.
                ServiceFactory.CreateBreastfeedingSignificanceService().Update(CurrentBreastfeedingSignificance);

                // Refresh the AnalysisItemList after update.
                SharedEntityStorage.LoadSharedAnalysisItemList(ServiceFactory);

                // Request to return to home page.
                Messenger.Default.Send<int>(0, MainViewModel.ReturnHomeMessageToken);
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        private bool CanExecuteSaveCommand()
        {
            return true;
        }

        /// <summary>
        /// Initialize the AnalysisItemList for binding.
        /// </summary>
        private void InitializeAnalysisItemList()
        {
            AnalysisItemList = new ObservableCollection<AnalysisItem>(SharedEntityStorage.AnalysisItemList.
                Where(p => p.ItemName != AnalysisItemDefinition.TrueProteinItemName));
        }

        private void InitializeBreastfeedingSignificance()
        {
            CurrentBreastfeedingSignificance = ServiceFactory.CreateBreastfeedingSignificanceService().GetAll().FirstOrDefault();
        }
    }
}
